import "babel/polyfill";
import {MathError} from "js-utilities/src/math/error";
import {isPrime} from "js-utilities/src/math/number-theory/prime";
import factorInteger, {prettyPrint as prettyPrintInteger} from "js-utilities/src/math/number-theory/factor";
import PolynomialZ from "js-utilities/src/math/polynomial/polynomial-Z";
import PolynomialZn from "js-utilities/src/math/polynomial/polynomial-Zn";
import factorZ from "js-utilities/src/math/polynomial/factor/factor-Z";
import factorZp from "js-utilities/src/math/polynomial/factor/factor-Zp";
import {prettyPrint as prettyPrintPolynomial} from "js-utilities/src/math/polynomial/factor/utility";

self.addEventListener("message", function(event) {
    var result;
    try {
        if (event.data.type === "integer") {
            result = factorInteger(event.data.number)::prettyPrintInteger();
        } else if (event.data.type === "polynomial") {
            let polynomial = event.data.polynomial;
            let characteristic = event.data.characteristic;
            let symbol = event.data.symbol;
            let PolynomialType, factorPolynomial;
            if (characteristic) {
                if (!isPrime(characteristic)) {
                    throw new MathError("Polynomial ring over Z or Z_p required");
                }
                PolynomialType = PolynomialZn(characteristic);
                factorPolynomial = PolynomialType::factorZp;
            } else {
                PolynomialType = PolynomialZ;
                factorPolynomial = factorZ;
            }
            result = factorPolynomial(new PolynomialType(polynomial, symbol))::prettyPrintPolynomial(symbol);
        }
        result = {status: "success", data: result};
    } catch (e) {
        result = {
            status: "fail",
            data: `${e.name}: ${e.message}`
        };
    }
    postMessage(result);
});
